<template>
  <view class="relative h-100vh w-full overflow-hidden flex flex-col justify-center items-center"
    :style="gradientStyle">
    <!-- 心形图标行 -->
    <view class="w-full flex justify-between px-20rpx">
      <text v-for="i in 9" :key="i" class="i-carbon-favorite text-60rpx" :class="{
        'text-yellow': i <= lastSpeed,
        'text-white': i > lastSpeed,
        'bg-yellow': i <= lastSpeed,
      }"></text>
    </view>

    <!-- 摇一摇图标和文字 -->
    <view class="flex flex-col justify-start items-center">
      <!-- 手机和震动波图标 -->
      <image src="../../static/shake.png" class="w-100rpx" mode="widthFix" />

      <!-- 文字说明 -->
      <text class="text-white text-60rpx font-bold mb-20rpx">摇一摇</text>
      <text class="text-white text-24rpx opacity-80">摇的越快，惊喜越多</text>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted, onUnmounted, computed } from "vue";
import { str2ab } from "../../utils/index";
import { throttle } from "lodash";
import { onReady, onUnload, onLoad } from "@dcloudio/uni-app";

let list = [
  "0x00",
  "0x01",
  "0x02",
  "0x03",
  "0x04",
  "0x05",
  "0x06",
  "0x07",
  "0x08",
  "0x09",
];

// 渐变背景样式
const gradientStyle = computed(() => {
  return {
    background:
      "linear-gradient(to bottom, #f472b6 0%, #f472b6 30%, #fb923c 100%)",
  };
});

// 摇一摇相关变量
const isShaking = ref(false);
const lastMsg = ref("");
const shakeThreshold = 15; // 摇动阈值

const lastSpeed = ref(0);
let lastUpdate = 0;
let lastX = 0,
  lastY = 0,
  lastZ = 0;

// 监听加速度计
const startAccelerometer = () => {
  uni.startAccelerometer({
    interval: "game", // 更新频率：game - 适用于游戏，更新频率约为 20ms/次
  });

  uni.onAccelerometerChange((res) => {
    const currentTime = Date.now();
    // 限制更新频率，避免过于频繁的计算
    if (currentTime - lastUpdate > 100) {
      const diffTime = currentTime - lastUpdate;
      lastUpdate = currentTime;

      const x = res.x;
      const y = res.y;
      const z = res.z;

      const speed = parseInt(
        (Math.abs(x + y + z - lastX - lastY - lastZ) / diffTime) * 10000
      );

      if (speed > shakeThreshold) {
        handleShake(speed % 10);
      } else {
        handleShake(0);
      }

      lastX = x;
      lastY = y;
      lastZ = z;
    }
  });
};

// 处理摇一摇事件
const handleShake = throttle((speed) => {
  lastSpeed.value = speed;

  if (!isShaking.value) {
    isShaking.value = true;
  }

  let msg = list[speed];

  if (msg === lastMsg.value) {
    return;
  }

  console.log("msg", msg);
  sendVibrationMode(msg);

  lastMsg.value = msg;
}, 500);

const sendVibrationMode = (msg) => {
  // 向蓝牙设备发送一个0x00的16进制数据
  return new Promise((resolve, reject) => {
    console.log("msg", msg);

    let buffer = str2ab(msg);
    console.log("msg", msg);
    console.log("buffer", buffer);

    console.log(
      "deviceId:" + deviceId.value,
      "serviceId:" + serviceId.value,
      "characteristicId:" + characteristicId.value
    );

    uni.writeBLECharacteristicValue({
      deviceId: deviceId.value,
      serviceId: serviceId.value,
      characteristicId: characteristicId.value,
      value: buffer,
      writeType: "write",
      success(res) {
        console.log("res", res);
        console.log("msg success", msg);
        resolve(res);
      },
      fail(err) {
        console.log("write指令发送失败", err);
        reject(err);
      },
    });
  });
};

// 页面加载时启动加速度计
onMounted(() => {
  startAccelerometer();
});

// 页面卸载时停止加速度计
onUnmounted(() => {
  uni.stopAccelerometer();
});

const deviceId = ref("");
const serviceId = ref("");
const characteristicId = ref("");
const name = ref("");
const advertisServiceUUIDs = ref([]);

onLoad(() => {
  deviceId.value = uni.getStorageSync("deviceId") || "";
  serviceId.value = uni.getStorageSync("serviceId") || "";
  characteristicId.value = uni.getStorageSync("characteristicId") || "";
  name.value = uni.getStorageSync("name") || "";
  advertisServiceUUIDs.value = uni.getStorageSync("advertisServiceUUIDs") || [];
});
</script>

<style>
.relative {
  position: relative;
}

.h-100vh {
  height: 100vh;
}

.w-full {
  width: 100%;
}

.overflow-hidden {
  overflow: hidden;
}

.flex {
  display: flex;
}

.flex-col {
  flex-direction: column;
}

.justify-center {
  justify-content: center;
}

.items-center {
  align-items: center;
}

.px-20rpx {
  padding-left: 20rpx;
  padding-right: 20rpx;
}

.text-60rpx {
  font-size: 60rpx;
}

.text-yellow {
  color: yellow;
}

.text-white {
  color: white;
}

.bg-yellow {
  background-color: yellow;
}

.justify-between {
  justify-content: space-between;
}

.w-100rpx {
  width: 100rpx;
}

.font-bold {
  font-weight: 700;
}

.mb-20rpx {
  margin-bottom: 20rpx;
}

.text-24rpx {
  font-size: 24rpx;
}

.opacity-80 {
  opacity: 0.8;
}
</style>
